//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<XFormView.h>
///	@path	~/src/editor/wm/
///	@date	2008/05/20
///	@desc	Container of an XForm.

#pragma once

#pragma message("Compiling XFormView.h ...")

#include "editor/editor.h"

#include "lib/utilities/time.h"

#include "gui/composite/composition.h"
#include "gui/xgui/XForm.h"

#include "editor/xedit/XEditorFrame.h"

namespace xeres {

	/*! 
		\class	XFormView
		\brief
	*/
	class XFormView : public CWindowImpl< XFormView > , public FrameBase
	{
	public:
		DECLARE_WND_CLASS( _T("xeres__XFormView") )

		/// \ctor
		XFormView( void ) {
			m_frame = new XEditorFrame( *this );
		}
		/// \dtor
		~XFormView( void ) {
			m_frame->OnClose();
		}

		BOOL PreTranslateMessage(MSG* pMsg)
		{
			UNREFERENCED_PARAMETER( pMsg );
			return FALSE;
		}

		virtual RefWeak<IGuiForm> GetClientForm( void )
		{
			return m_frame;
		}

		virtual void AcquireUpdate( void )
		{
			Invalidate( FALSE );
		}

		virtual void SetTitle( const wchar_t * title )
		{
			SetWindowText( title );
		}

		virtual HWND GetHwnd( void )
		{
			return m_hWnd;
		}

		BEGIN_MSG_MAP(XFormView)
			MESSAGE_HANDLER(WM_ACTIVATE , OnActivate)
			MESSAGE_HANDLER(WM_CREATE, OnCreate)
			MESSAGE_HANDLER(WM_PAINT , OnPaint)
			MESSAGE_HANDLER(WM_SIZE , OnSize)
			MESSAGE_HANDLER(WM_ERASEBKGND , OnEraseBkgnd)
			MESSAGE_HANDLER(WM_SETFOCUS , OnSetFocus)
			MESSAGE_HANDLER(WM_KILLFOCUS , OnKillFocus)
// 			MESSAGE_HANDLER(WM_MOUSEMOVE , OnMouseMove)
// 			MESSAGE_HANDLER(WM_MOUSELEAVE , OnMouseLeave)
		// Dispatch message to XForm.
			if( m_frame->DispatchMessages( m_hWnd , uMsg , wParam , lParam ) ) return TRUE; else bHandled = FALSE;
		END_MSG_MAP()

		LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
			// Dummy filter to refresh dispatcher states.
			m_frame->RefreshStates( m_hWnd );
			bHandled = FALSE;
			return S_OK;
		}
		LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {

			// Setup ticking timer (30fps).
			this->SetTimer( TIMER_TICK , static_cast<int>( 1000.f / 30.f ) );

			return S_OK;
		}
		LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
			CPaintDC dc( m_hWnd );

			RECT client;
			this->GetClientRect( &client );

			Layer& layer = m_frame->GetLayer();

			int w = RectWidth( client );
			int h = RectHeight( client );
			dc.StretchDIBits( client.left , client.top , w , h ,
				0 , 0 , layer.GetWidth() , layer.GetHeight() , layer.GetPixel(0,0) , layer.GetBitmapInfo() ,
				DIB_RGB_COLORS , SRCCOPY );

			return S_OK;
		}
		LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ) {
			// re-create new painting buffer
			RECT client;
			this->GetClientRect( &client );

			int w = client.right - client.left;
			int h = client.bottom - client.top;
			if( w == 0 || h == 0 )
				return S_OK;

			m_frame->Resize( w , h );

			bHandled = FALSE;
			return S_OK;
		}
		LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
			return S_OK;
		}
		LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
			m_frame->ClearFocus();
			bHandled = FALSE;
			return S_OK;
		}
		LRESULT OnKillFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
			m_frame->ClearFocus();
			bHandled = FALSE;
			return S_OK;
		}
		LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ) {
			::SetCapture( m_hWnd );
			bHandled = FALSE;
			return S_OK;
		}
		LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
			Updater updater( m_frame );
			m_frame->OnMouseLeave( updater , NULL );
			bHandled = FALSE;
			return S_OK;
		}

		RefWeak<XEditorFrame> GetFrame( void )
		{
			return m_frame;
		}

	private:

		//@ data
		Ref<XEditorFrame>			m_frame;
	};

} // namespace xeres
